import random
import math
from collections import Counter


def euclidean_distance(point1, point2):
    """计算欧氏距离"""
    return math.sqrt(sum((x - y) ** 2 for x, y in zip(point1, point2)))


def knn_predict(X_train, y_train, X_test, k=3):
    """KNN 预测函数"""
    predictions = []
    for test_point in X_test:
        # 计算测试点与所有训练点的距离
        distances = [euclidean_distance(test_point, train_point) for train_point in X_train]
        # 获取距离最近的 k 个点的索引
        k_indices = sorted(range(len(distances)), key=lambda i: distances[i])[:k]
        # 获取这 k 个点的标签
        k_nearest_labels = [y_train[i] for i in k_indices]
        # 统计标签出现次数，返回最常见的标签
        most_common = Counter(k_nearest_labels).most_common(1)
        predictions.append(most_common[0][0])
    return predictions


if __name__ == "__main__":
    # 生成随机训练数据
    random.seed(42)
    X_train = [[random.uniform(0, 10), random.uniform(0, 10)] for _ in range(100)]  # 100 个二维训练点
    y_train = [random.randint(0, 1) for _ in range(100)]  # 随机生成标签 (0 或 1)

    # 生成随机测试数据
    X_test = [[random.uniform(0, 10), random.uniform(0, 10)] for _ in range(5)]  # 5 个二维测试点

    # 使用 KNN 进行预测
    k = 3
    predictions = knn_predict(X_train, y_train, X_test, k)
    print(f"测试点预测结果: {predictions}")